// ONLY DIFFERENCE IN RAM PARAM & NAME

//read_data_channel_instr_fifo
module sync_fifo_d64_w73 
  (
    input  wire           clk,
    input  wire           rstn,
    
    output wire           full,
    output wire           almost_full,
    input  wire [72:0]    din,
    input  wire           wr_en,

    input  wire [9:0]     ram_2p_cfg_register,
    
    output wire           empty,
    input  wire           rd_en,
    output reg  [72:0]    dout
  );

`ifdef ORIGINAL_FIFOCTL

    localparam Depth = 1 << 6; //64
    reg [6:0]    cnt; //0~64
    reg [5:0]    wp; //0~63
    reg [5:0]    rp;
    
    assign empty = (cnt == 0) ? 1'b1 : 1'b0;
    assign full  = (cnt == Depth) ? 1'b1:1'b0;
    assign almost_full = (cnt >= Depth-'d3) ? 1'b1:1'b0;
    
    always@(posedge clk or negedge rstn)
    begin
        if(!rstn)
            cnt <= 1'b0;
        else if(!empty & rd_en & !full & wr_en)
            cnt <= cnt;
        else if(!full & wr_en)
            cnt <= cnt + 1'b1;
        else if(!empty & rd_en)
            cnt <= cnt - 1'b1;
        else
            cnt <= cnt;
    end
    
    always@(posedge clk or negedge rstn)
    begin
        if(!rstn)
            rp <= 1'b0;
        else if(!empty & rd_en)
            rp <= rp + 1'b1;
        else
            rp <= rp;
    end
    
    always@(posedge clk or negedge rstn)
    begin
        if(!rstn)
            wp <= 1'b0;
        else if(!full & wr_en)
            wp <= wp + 1'b1;
        else
            wp <= wp;
    end
    
`else

wire   mem_wen;
wire [5:0] mem_waddr;
wire [5:0] mem_raddr;

DW_fifoctl_s1_sf #
(
    .depth      ('d64),
    .ae_level   ('d1),
    .af_level   ('d3),
    .err_mode   (0),
    .rst_mode   (0)
)
u_fifo_ctl
(
    .clk          (clk),
    .rst_n        (rstn),
    .push_req_n   (~wr_en),
    .pop_req_n    (~rd_en),
    .diag_n       (1'b1),
    .we_n         (mem_wen),
    .empty        (empty),
    .almost_empty (),
    .half_full    (),
    .almost_full  (almost_full),
    .full         (full),
    .error        (),
    .wr_addr      (mem_waddr),
    .rd_addr      (mem_raddr)
);

`endif

    wire         mem_rd_en;
    reg          mem_rd_en_ff;

    assign  mem_rd_en = !empty & rd_en;

    always @(posedge clk or negedge rstn)
    begin
        if (!rstn)
            mem_rd_en_ff <= 'd0 ;
        else
            mem_rd_en_ff <= mem_rd_en;
    end

    wire [72:0] rdata;

    always@(posedge clk or negedge rstn)
    begin
        if(!rstn)
            dout <= 1'b0;
        else if(mem_rd_en_ff)
            dout <= rdata;
        else
            dout <= dout;
    end
//======================================================================================================
// FIFO MEM
`ifdef FPGA
`else
    ram_2p_d64_w73_wrapper U_ram_2p_d64_w73_wrapper (
        .clk(clk),
        .ram_2p_cfg_register(ram_2p_cfg_register),
        .wren(~mem_wen),
        .waddr(mem_waddr),
        .wdata(din),
        .rden(1'b1),//(mem_rd_en)
        .raddr(mem_raddr),
        .rdata(rdata)
    );
`endif

endmodule
